﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using HR.Appointments.Service.ValueObjects;

namespace HR.Appointments.Service.Test
{
    [TestFixture]
    public class TestTimeUnit
    {
        [Test]
        public void TimeIsNotNull()
        {
            TimeUnit time = TimeUnit.Create(1, 35);
            Assert.IsNotNull(time);
        }

        [Test]
        public void TimeFormat()
        {
            TimeUnit time = TimeUnit.Create(1, 35);
            Assert.AreEqual("01:35", time.ToString());

            time = TimeUnit.Create(11, 0);
            Assert.AreEqual("11:00", time.ToString());

            time = TimeUnit.Create(0, 44);
            Assert.AreEqual("00:44", time.ToString());

            time = TimeUnit.Create(23, 05);
            Assert.AreEqual("23:05", time.ToString());

            time = TimeUnit.Create(0, 0);
            Assert.AreEqual("00:00", time.ToString());
        }

        [Test]
        public void TimeIsEqual()
        {
            TimeUnit time = TimeUnit.Create(1, 1);
            Assert.AreEqual(time, TimeUnit.Create(1, 1));
            Assert.AreNotEqual(time, TimeUnit.Create(1, 2));
        }

        [Test]
        public void TimeAreSame()
        {
            TimeUnit time = TimeUnit.Create(1, 1);
            Assert.AreSame(time, time);
            Assert.AreNotSame(time, TimeUnit.Create(1, 1));
        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void OverTimeIfHourIs24()
        {
            TimeUnit time = TimeUnit.Create(24, 00);
            
        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void OverTimeIfHourIsNegative()
        {
            TimeUnit time = TimeUnit.Create(-1, 00);

        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void OverTimeIfMinuteIs60()
        {
            TimeUnit time = TimeUnit.Create(1, 60);
        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void OverTimeIfMinuteIsNegative()
        {
            TimeUnit time = TimeUnit.Create(1, -1);
        }

        [Test]
        public void AddTime()
        {
            var time = TimeUnit.Create(1, 0);
            time.Add(30);
            Assert.AreEqual(TimeUnit.Create(1, 30), time);

            time = TimeUnit.Create(1, 59);
            time.Add(1);
            Assert.AreEqual(TimeUnit.Create(2, 0), time);

            time = TimeUnit.Create(23, 51);
            time.Add(10);
            Assert.AreEqual(TimeUnit.Create(0, 1), time);

        }

        [Test]
        public void CheckNextDay()
        {
            var time = TimeUnit.Create(1, 59);
            time.Add(1);
            Assert.IsFalse(time.IsNextDay);
            
            time = TimeUnit.Create(23, 51);
            time.Add(10);
            Assert.IsTrue(time.IsNextDay);
        }

        [Test]
        public void CreateFromString()
        {
            var time = TimeUnit.Create("09:30");
            Assert.AreEqual(time.Hour, 9);
            Assert.AreEqual(time.Minute, 30);

            time = TimeUnit.Create("23:00");
            Assert.AreEqual(time.Hour, 23);
            Assert.AreEqual(time.Minute, 0);
        }

        [Test]
        public void ReturnClonedInstanceOnAdd()
        {
            var time = TimeUnit.Create("09:30");
            var timeClone = time.Add(10);

            Assert.AreEqual(time, timeClone);
            Assert.AreNotSame(time, timeClone);
        }

        [Test]
        public void TimeAddMoreThen60()
        {
            var time = TimeUnit.Create("09:30");
            time.Add(60);
            Assert.AreEqual(TimeUnit.Create(10, 30), time);

            time.Add(125);
            Assert.AreEqual(TimeUnit.Create(12, 35), time);

        }

        [Test]
        [ExpectedException(typeof(ArgumentOutOfRangeException))]
        public void AddMoreThenAHoleDay()
        {
            var time = TimeUnit.Create("09:30");
            time.Add(1440);
        }

        [Test]
        public void AddAlmostAnHoleDay()
        {
            var time = TimeUnit.Create("09:30");
            time.Add(1439);
            Assert.AreEqual(TimeUnit.Create("09:29"), time);
        }

    }
}